<?php

namespace app\api\service;

use app\common\model\Agent;
use app\common\model\CommissionLog;
use app\common\model\haipi\Order as OrderModel;
use app\common\model\User;
use app\common\model\user\Vip;
use app\common\model\user\VipExpire;
use think\facade\Db;
use think\facade\Log;

class OrderService
{
    private const SECONDS_PER_DAY = 86400;

    public function callback($tradeNo, $payTime)
    {
        $order = $this->findOrder($tradeNo);
        
        if (!$order) {
            throw new \Exception('订单不存在');
        }

        if($order->pay_time){
            throw new \Exception('订单已支付');
        }

        $order->pay_time = $payTime;
        $order->status = OrderModel::ORDER_STATUS_PAIED;
        Db::transaction(function() use ($order) {
            $order->save();
            $this->handleGoods($order);
            $this->handleCommission($order->user,$order);
        });
    }

    private function findOrder($tradeNo)
    {
        return OrderModel::where('trade_no', $tradeNo)->find();
    }

    public static function getValidTime($time){
        $timeout = get_sys_config('timeout', 'vpay');
        $time = strtotime($time);
        $time += $timeout * 60;
        return date('Y-m-d H:i:s', $time);
    }

    public function handleGoods(OrderModel $order)
    {
        switch ($order->goods_type) {
            case OrderModel::GOODS_TYPE_VIP:
                $userinfo = User::where('id', $order->user_id)->find();
                $vipLevel = Vip::where('id', $order->goods_id)->find();
                $this->handleVip( $userinfo, $vipLevel);
                break;
            default:
                break;
        }
    }

    public function handleVip(User $userinfo, Vip $vipLevel)
    {
        $lastVip = $userinfo->userVipExpire();
        $addDayNum = $vipLevel->expire_day_num;
        $data = [
            'vip_id' => $vipLevel->id,
            'user_id' => $userinfo->id,
            'is_long' => $addDayNum == 0 ? 1 : 0,
            'add_day_num' => $addDayNum,
            'expire_time' => $this->calculateExpireDate($lastVip, $addDayNum),
        ];

        VipExpire::create($data);
    }

    private function calculateExpireDate($lastVip, $addDayNum)
    {
        $expireDate = $lastVip
            ? strtotime($lastVip['expire_time']) + ($addDayNum * self::SECONDS_PER_DAY)
            : time() + ($addDayNum * self::SECONDS_PER_DAY);

        return date('Y-m-d H:i:s', $expireDate);
    }

    public function handleCommission(User $userinfo, OrderModel $order){
        if(empty($userinfo->agent_id)){
            return ;
        }
        $agent = Agent::where('id', $userinfo->agent_id)->find();
        $commiss = round(($order->amount * $agent->commission_rate) / 100, 2);
        CommissionLog::create([
            'order_id' => $order->id,
            'agent_id' => $userinfo->agent_id,
            'amount' => $commiss
        ]);
        $agent->money = $agent->money + $commiss;
        $agent->save();
    }


    public function createOrder($userId, $amount, $type, $goodsId,$payType, $traceNo){
        $timeout = get_sys_config('timeout', 'vpay');
        $data = [
                'user_id' => $userId,
                'amount' => $amount,
                'status' => OrderModel::ORDER_STATUS_NOPAY,
                'goods_type' => $type,
                'expire_time'=> date('Y-m-d H:i:s', time() + $timeout *60),
                'goods_id' => $goodsId,
                'pay_type' => $payType,
                'order_no' => date('YmdHis') . mt_rand(1000, 9999) . $userId,
                'trade_no' => $traceNo
        ];

        if ($payType == OrderModel::PAY_TYPE_BALANCE){
            $data['status'] = OrderModel::ORDER_STATUS_PAIED;
            $data['pay_time'] = date('Y-m-d H:i:s', time());
        }
        return OrderModel::create($data);
    }

    public function generateUniqueNo(){
        return date('YmdHis').uniqid(strval(mt_rand(1000, 9999)));
    }

}